﻿using Abp.BackgroundJobs;
using Abp.Domain.Repositories;
using Abp.Domain.Services;
using Abp.Domain.Uow;
using Mt.Site.Core.BackGroundJobs;
using Mt.Site.Core.BackGroundJobs.Navigations;
using Mt.Site.Core.Navigations.Entities;
using Mt.Site.Core.Synchronization.Data;
using Mt.Site.Core.Synchronization.Storage;
using System;

namespace Mt.Site.Core.Synchronization.Navigations
{
    public class MenuInfoManualSyncManager : DomainService, IMenuInfoManualSyncManager
    {
        private readonly IRepository<ChannelObject, Guid> _channelObjectRepository;
        private readonly IRepository<MenuConfig, Guid> _menuConfigRepository;

        private readonly ISynchronizationHelper _synchronizationHelper;

        private readonly IMenuInfoStore _menuInfoStore;
        private readonly IBackgroundJobManager _backgroundJobManager;

        private readonly IFileObjectManualSyncManager _fileObjectManualSyncManager;

        public MenuInfoManualSyncManager(
            ISynchronizationHelper synchronizationHelper,
            IRepository<ChannelObject, Guid> channelObjectRepository,
            IRepository<MenuConfig, Guid> menuConfigRepository,
            IMenuInfoStore menuInfoStore,
            IFileObjectManualSyncManager fileObjectManualSyncManager,
            IBackgroundJobManager backgroundJobManager)
        {
            _synchronizationHelper = synchronizationHelper;

            _channelObjectRepository = channelObjectRepository;
            _menuConfigRepository = menuConfigRepository;
            _menuInfoStore = menuInfoStore;
            _backgroundJobManager = backgroundJobManager;
            _fileObjectManualSyncManager = fileObjectManualSyncManager;
        }

        #region Config

        [UnitOfWork]
        public Guid CreateOrUpdateConfigManualSync(CreateOrUpdateSynchorizeStore input)
        {
            //目标分站是否开启数据同步功能
            if (!_synchronizationHelper.ShouldSynchronize(input.ToTenantId))
            {
                return Guid.Empty;
            }

            using (CurrentUnitOfWork.DisableFilter(
                AbpDataFilters.MayHaveTenant,
                AbpDataFilters.MustHaveTenant,
                MtSiteConsts.AbpDataFilters.MustHaveLanguage,
                AbpDataFilters.SoftDelete))
            {
                var fromEntity = _menuConfigRepository.FirstOrDefault(input.Id);
                if (fromEntity != null)
                {
                    var toEntity = _menuConfigRepository.FirstOrDefault(
                            item => item.TenantId == input.ToTenantId && item.MenuId == fromEntity.MenuId && item.Type == fromEntity.Type);

                    Guid toEntityId;
                    if (toEntity != null)
                    {
                        input.OptionType = OptionType.Update;
                        toEntityId = _menuInfoStore.UpdateConfigSync(toEntity, fromEntity);
                    }
                    else
                    {
                        input.OptionType = OptionType.Create;
                        toEntityId = _menuInfoStore.CreateConfigSync(fromEntity, new SynchorizeBaseStore
                        {
                            ToTenantId = input.ToTenantId,
                            TargetLanguage = input.TargetLanguage,
                        });
                    }

                    if (toEntityId != Guid.Empty)
                    {
                        //自动同步
                        _backgroundJobManager.Enqueue<SynchorizationMenuConfigJob, BaseAndMenuIdArgs>(
                                new BaseAndMenuIdArgs
                                {
                                    Id = toEntityId,
                                    FromLanguage = input.TargetLanguage,
                                    FromTenantId = input.ToTenantId,
                                    MenuId = fromEntity.MenuId,
                                    OperateType = input.OptionType
                                });
                    }
                    return toEntityId;
                }
                return Guid.Empty;
            }
        }

        #endregion

        #region ImgText

        [UnitOfWork]
        public Guid CreateOrUpdateImgTextSync(SyncArgs_Guid input)
        {
            //目标分站是否开启数据同步功能
            if (!_synchronizationHelper.ShouldSynchronize(input.ToTenantId))
            {
                return Guid.Empty;
            }

            using (CurrentUnitOfWork.DisableFilter(
                AbpDataFilters.MayHaveTenant,
                AbpDataFilters.MustHaveTenant,
                MtSiteConsts.AbpDataFilters.MustHaveLanguage,
                AbpDataFilters.SoftDelete))
            {
                var fromEntity = _channelObjectRepository.FirstOrDefault(input.Id);
                if (fromEntity != null)
                {
                    var toEntity = _channelObjectRepository.FirstOrDefault(
                            item => item.TenantId == input.ToTenantId && item.SourceID == fromEntity.Id && item.Language == input.TargetLanguage);

                    Guid toEntityId = Guid.Empty;
                    if (toEntity != null)
                    {
                        input.OptionType = OptionType.Update;
                        toEntityId = _menuInfoStore.UpdateChannelObjectSync(toEntity, fromEntity);
                    }
                    else
                    {
                        var menuId = _synchronizationHelper.GetMenuId(input.MenuId, input.ToTenantId);
                        if (menuId != Guid.Empty)
                        {
                            input.OptionType = OptionType.Create;
                            toEntityId = _menuInfoStore.CreateChannelObjectSync(fromEntity, new SynchorizeBaseStore
                            {
                                ToTenantId = input.ToTenantId,
                                TargetLanguage = input.TargetLanguage,
                            }, menuId);
                        }
                    }

                    if (toEntityId != Guid.Empty)
                    {
                        CreateOrUpdateFileInfoSync(input, toEntityId, fromEntity.TenantId, fromEntity.Language, fromEntity.Id);

                        _backgroundJobManager.Enqueue<SynchorizationImgTextJob, BaseAndMenuIdArgs>(
                                new BaseAndMenuIdArgs
                                {
                                    Id = toEntityId,
                                    FromLanguage = input.TargetLanguage,
                                    FromTenantId = input.ToTenantId,
                                    MenuId = input.MenuId,
                                    OperateType = input.OptionType
                                });
                    }
                    return toEntityId;
                }
                return Guid.Empty;
            }
        }

        #endregion

        private void CreateOrUpdateFileInfoSync(SyncArgs_Guid input, Guid toContentId, int fromTenantId, string fromLanguage, Guid fromContentId)
        {
            _fileObjectManualSyncManager.CreateOrUpdateFileObjectManualSync(
                    new FileObjectSyncStore
                    {
                        FromContenId = fromContentId,
                        FromLanguage = fromLanguage,
                        FromTenantId = fromTenantId,
                        ToContentId = toContentId,
                        ToLanguage = input.TargetLanguage,
                        ToTenantId = input.ToTenantId
                    });
        }
    }
}
